package main

import "fmt"

// 结构体赋值时 会拷贝数据
func S8() {
	type s1 struct {
		name string
		age  int
	}

	var v1 s1 = s1{"myc", 18}
	v2 := v1
	v2.name = "djr"

	// 发现v2在修改值后，v1不会变
	fmt.Println(v1, v2)
}

// 结构体通过指针赋值， 值会变
func S9() {
	type s1 struct {
		name string
		age  int
	}

	var p1 *s1 = new(s1)
	p1.name = "myc"
	p1.age = 18

	// 当通过指针赋值时， 因指针指向的时同一块内存地址， 所以p2改变后， p1也会改变
	p2 := p1
	p2.age = 100
	fmt.Println(p1, p2)
}

// 嵌套结构体赋值， 被嵌套的结构体也会被拷贝
func S10() {
	type s1 struct {
		name string
		age  int
	}
	type s2 struct {
		hobby string
		s1
	}

	var v1 s2 = s2{hobby: "hobby", s1: s1{name: "myc", age: 18}}

	var v2 = v1
	v2.name = "djr"
	fmt.Println(v1, v2)
}

// 结构体中各种类型的数据赋值时 是否会拷贝

func S11() {
	type s1 struct {
		name  string
		age   int8
		hobby [2]string
		car   []string
		pc    map[int]string
	}

	var v1 s1 = s1{
		name:  "myc",
		age:   18,
		hobby: [2]string{"Mauy Thai", "Piano"},
		car:   []string{"benz", "Aodi"},
		pc:    map[int]string{1: "alienware", 2: "saver"},
	}
	v2 := v1
	fmt.Printf("v1未修改前%+v\n", v1)
	fmt.Printf("v2未修改前%+v\n", v2)

	// 这里在表面上看着 v2的切片和map修改后，v1的值也变了
	// 但其实 v2是一个完整的复制，
	// v1的值变化是因为，切片和map的类型 他们其实是在内部存储了一个指针
	// 这个指针指向了真实的数据地址
	// 当v2复制v1的切片和map时，复制的是这些类型存储的值，也就等于复制了v1切片和map的指针
	// 但指针指向的地址还是相同的. 所以修改数据的时候 修改的是指针指向的数据， 这样v1 就会随着 v2改变而改变
	v2.name = "djr"
	v2.age = 38
	v2.hobby[0] = "picture"
	v2.car[0] = "MiNi"
	v2.pc[1] = "2019MAC"
	fmt.Printf("v1修改%+v\n", v1)
	fmt.Printf("v2修改%+v\n", v2)
}
